﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using EPiServer;
using EPiServer.Core;

namespace EPiCloner
{
    public partial class Cloner
    {
        List<Delegate> creatingEvents = new List<Delegate>(),
                       createdEvents = new List<Delegate>(),
                       savingEvents = new List<Delegate>(),
                       savedEvents = new List<Delegate>(),
                       publishingEvents = new List<Delegate>(),
                       publishedEvents = new List<Delegate>(),
                       movingEvents = new List<Delegate>(),
                       movedEvents = new List<Delegate>(),
                       deletingEvents = new List<Delegate>(),
                       deletedEvents = new List<Delegate>();

        private void EnablePageEvents(object sender, EventArgs e)
        {
            EnableEvents("CreatingPage", creatingEvents);
            EnableEvents("CreatedPage", createdEvents);
            EnableEvents("SavingPage", savingEvents);
            EnableEvents("SavedPage", savedEvents);
            EnableEvents("PublishingPage", publishingEvents);
            EnableEvents("PublishedPage", publishedEvents);
            EnableEvents("MovingEvent", movingEvents);
            EnableEvents("MovedEvent", movedEvents);
            EnableEvents("DeletingEvent", deletingEvents);
            EnableEvents("DeletedEvent", deletedEvents);
        }

        private void DisablePageEvents(object sender, EventArgs e)
        {
            DisableEvents("CreatingEvent", "CreatingPage", creatingEvents);
            DisableEvents("CreatedEvent", "CreatedPage", createdEvents);
            DisableEvents("SavingEvent", "SavingPage", savingEvents);
            DisableEvents("SavedEvent", "SavedPage", savedEvents);
            DisableEvents("PublishingEvent", "PublishingPage", publishingEvents);
            DisableEvents("PublishedEvent", "PublishedPage", publishedEvents);
            DisableEvents("MovingEvent", "MovingPage", movingEvents);
            DisableEvents("MovedEvent", "MovedPage", movedEvents);
            DisableEvents("DeletingEvent", "DeletingPage", deletingEvents);
            DisableEvents("DeletedEvent", "DeletedPage", deletedEvents);

        }

        private void DisableEvents(string fieldName, string eventName, List<Delegate> delegates)
        {
            try
            {
                var key = typeof(DataFactory).GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic).GetValue(DataFactory.Instance);
                var events = (EventHandlerList)typeof(PageStoreBase).GetField("_events", BindingFlags.Instance | BindingFlags.NonPublic).GetValue(DataFactory.Instance);
                var eh = events[key];

                if (eh != null)
                {
                    foreach (var del in eh.GetInvocationList())
                    {
                        if (!del.Method.Module.Assembly.FullName.StartsWith("EPiServer"))
                        {
                            delegates.Add(del);
                            typeof(DataFactory).GetEvent(eventName).RemoveEventHandler(DataFactory.Instance, del);
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }

        private void EnableEvents(string eventName, List<Delegate> delegates)
        {
            try
            {
                foreach (var @delegate in delegates)
                {
                    var eventInfo = typeof(DataFactory).GetEvent(eventName);
                    if (eventInfo != null)
                    {
                        eventInfo.AddEventHandler(DataFactory.Instance, @delegate);
                    }
                }
            }
            catch (Exception)
            {
            }
        }
    }
}